/* $Id:background.cc $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#define DEBUG_ROUTINE "background"

#include <sstream>
#include <fstream>
#include "../general/util.h"
#include "../general/log.h"
#include "../general/channel.h"
#include "background.h"
#include "../general/general.h"
#include "action.h"

background::background() {
    name="";
    nr=0;
    description="";
    skills=map<string,class skill>();
}

// Field : name

const string background::getName() const { return name; }
void background::setName(const string v) { name=v; }

// Field : nr

const int background::getNr() const { return nr; }
void background::setNr(const int v) { nr=v; }
int background::operator<(const class background &ck) const { return (this->nr < ck.nr)?1:0; }

// Field : description

const string background::getDescription() const { return description; }
void background::setDescription(const string v) { description=v; }

// Field : skills

class skill& background::getSkills(const string v) { return skills[v]; }
map<string,class skill>& background::listSkills() { return skills; }
void background::setSkills(class skill &v) {
    if (v.getName()=="") throw unnamed();
    skills[v.getName()]=v;
}
void background::delSkills(const string v) { skills.erase(v); }
const bool background::isSkills(const string v) const { return skills.count(v)>0; }

void background::save(class channel &ch) {
    ch.write("background", "");
    ch.write("n", getName());
    ch.write("nr", getNr());
    ch.write("d", getDescription());
    loopBackgroundSkills(this, s_skills) {
        s_skills->save(ch);
    }
}

void background::load(class channel &ch) {
    if (ch.key=="n" || ch.key=="name") { setName(ch.value); ch.next(); }
    if (ch.key=="nr" || ch.key=="nr") { setNr(atoi(ch.value.c_str())); ch.next(); }
    if (ch.key=="d" || ch.key=="description") { setDescription(ch.value); ch.next(); }
    while (ch.key=="skill" || ch.key=="skills") {
        ch.next();
        class skill rec;
        rec.load(ch);
        setSkills(rec);
        while (ch.key=="action" && ch.value=="") action_repo.load(ch);
    }
}

void background::xml(ofstream &f, int l, int r) {
    f << ncpy(l, "  ") << "<background name=\"" << xml_encode(getName()) <<
    "\" nr=\"" << getNr() <<
    "\" description=\"" << xml_encode(getDescription()) <<
    "\">" << endl;
    if (r==0) {
        loopBackgroundSkills(this, s_skills) {
            s_skills->xml(f,l+1);
        }
    }
    f << ncpy(l, "  ") << "</background>" << endl;
}

// Repository

backgroundRepository background_repo;

backgroundRepository::backgroundRepository() { max_nr=0; }
class background& backgroundRepository::getBackground(const string v) { return backgrounds[v]; }
void backgroundRepository::setBackground(class background& v) {
    if (v.getNr()==0) v.setNr(++max_nr);
    if (v.getName()=="") throw unnamed();
    backgrounds[v.getName()]=v;
}
list<class background>& backgroundRepository::listBackground() {
    static list<class background> res;
    res.clear();
    loopMap(backgrounds,v,class background) {
        res.push_back(*v);
    }
    res.sort();
    return res;
}
void backgroundRepository::delBackground(const string v) { backgrounds.erase(v); }
const bool backgroundRepository::isBackground(const string v) const { return backgrounds.count(v)>0; }
void backgroundRepository::save(class channel &ch) {
    loopBackgrounds(rec) {
        rec->save(ch);
    }
}

bool backgroundRepository::load(class channel &ch) {
    if (ch.key=="background") {
        ch.next();
        class background rec;
        rec.load(ch);
        setBackground(rec);
        return true;
    }
    if (action_repo.load(ch)) return true;
    dbg_state("end background");
    return false;
}
